<?php
/**
 * @author Amissah Gideon<kuulmek@yahoo.com>
 * @access public
 * @version 1.0
 */

class SalesController extends AppController
{
    # Controller Name to be used
    var $name = 'Sales';

    # Models to be used
    var $uses = array(
        'Sale',
        'Customer',
        'Item',
        'SaleCreditPayment',
        'Proforma'
    );

    # set the layout to use
    var $layout = 'sales_layout';

    # set the name of this module
    var $moduleName = 'Sales';

    # Check the authenticity of the user
    function  beforeFilter()
    {
        parent::beforeFilter($this->moduleName);
        parent::setUpGlobalConfig();
    }

    # Controller actions
    /**
     * This function displays all the users in the system
     * @name index
     * @param void
     * @return Array of data.
     * @access public
     */
    function index(){
        $customer_data = Set::combine($this->Customer->find('all', array('fields' => array('id', 'name'), 'conditions' => array('deleted' => 'n'), 'recursive' => -1)), '{n}.Customer.id', '{n}.Customer');
        $customerOpt = array();
        foreach ($customer_data as $value) {
            $customerOpt[$value['id']] = strtoupper($value['name']);
        }

        $Item_data = Set::combine($this->Item->find('all', array(
            'fields' => array('id', 'name', 'currency', 'amount', 'interest','insurance_amt','insurance_currency'),
            'conditions' => array('deleted' => 'n'),
            'recursive' => -1)), '{n}.Item.id', '{n}.Item'
        );
        $ItemOpt = array();
        $global_item_data = array();
        foreach ($Item_data as $value) {
            $ItemOpt[$value['id']] = strtoupper($value['name']);
            $global_item_data[$value['id']] = array(
                'name' => strtoupper($value['name']),
                'currency' => $value['currency'],
                'amount' => $value['amount'],
                'interest' => $value['interest'],
                'insurance_amt' => $value['insurance_amt'],
                'insurance_currency' => $value['insurance_currency']
            );
        }

        $pay_type_opt = $this->payment_types;
        $currency_opts = $this->currency_types;
        $buying_usd_rate = $this->buying_usd_rate;
        $selling_usd_rate = $this->selling_usd_rate;

        $page_title = 'New Sale';

        $this->set(compact('page_title','pay_type_opt', 'customerOpt', 'ItemOpt', 'global_item_data', 'currency_opts', 'buying_usd_rate', 'seling_usd_rate'));
    }

    /**
     * This function add a new record to the database
     * @name add
     * @param void
     * @return Json data
     * @access public
     */
    function add()
    {
        # Get the user session data
        $loggedUser = $this->Auth->user();
        # check whether the HTTP Request is an ajax request
        if ($this->request->is('ajax')) {
            # disable the rendering of the layout
            $this->autoRender = false;
            $this->autoLayout = false;
            # retrieve the model
            $model = ucfirst($_POST['model']);
            # Check the model
            switch ($model) {
                case 'Sale' :
                    $data = json_decode($_POST['data'], true);
                    $loggedUser_id = $loggedUser['id'];

                    $this->Sale->create();

                    $d1 = $data['Sale']['purchased_date']; //Smaller date
                    $purchase_date = $data['Sale']['purchased_date'];
                    $months_duration = $data['Sale']['duration_in_month'];
                    //$data['Sale']['end_date'] = date($purchase_date, strtotime("+".$months_duration." month"));
                    $data['Sale']['end_date'] = date("Y-m-d", strtotime(date("Y-m-d", strtotime($purchase_date)) . " +$months_duration month"));
                    //$d2 = $data['Sale']['end_date']; //Bigger date
                    //$duration_in_month = $this->count_months_between_dates($d1, $d2);
                    //$data['Sale']['duration_in_month'] = $duration_in_month;
                    $next_auto_number = $this->Sale->getNextAutoIncrement();

                    $invoice_number = "YGL" . date("Ymd", strtotime($purchase_date)) . $next_auto_number;
                    $data['Sale']['invoice_number'] = $invoice_number;

                    $data['Sale']['created_by'] = $loggedUser_id;
                    $opening_bal = floatval($data['Sale']['opening_bal']);
                    if ($data['Sale']['full_or_credit'] == 'full') {
                        $data['Sale']['on_credit'] = 'n';
                    }

                    # save the data
                    if ($this->Sale->saveAll($data)) {
                        if($data['Sale']['full_or_credit'] == 'full'){
                            $data2['SaleCreditPayment'] = array(
                                'sale_id'=> $this->Sale->id,
                                'paid_amount_currency'=>$data['Sale']['deposit_currency'],
                                'original_paid_amount'=>$data['Sale']['original_deposit_amt'],
                                'paid_amount'=>$data['Sale']['deposit'],
                                'currency'=>$data['Sale']['currency'],
                                'pay_date'=>$data['Sale']['purchased_date'],
                                'pay_type'=>$data['Sale']['payment_type'],
                                'comments'=>$data['Sale']['comments'],
                                'created_by' => $loggedUser_id
                            );

                            $this->SaleCreditPayment->save($data2['SaleCreditPayment']);
                        }
                        $last_dt = $data['Sale']['purchased_date'];

                        $d = new DateTime($last_dt);
                        $d->modify('next month');

                        $data_r = array(
                            'id' => $this->Sale->id,
                            'last_paid_date' => $last_dt,
                            'next_credit_date' => $d->format('Y-m-d'),
                            'duration_in_month' => $data['Sale']['duration_in_month']

                        );

                        //Cache the last customer and sale the user was working with
                        $last_entry = array('Sale'=>array(
                            'id'=>$this->Sale->id,
                            'customer_id'=>$data['Sale']['customer_id']
                        ));
                        $this->Session->write('last_entry',$last_entry);

                        return json_encode(array('code' => 0, 'data' => $data_r, 'mesg' => __('Data Saved')));
                    }
                    else {
                        return json_encode(array('code' => 1, 'mesg' => $this->Sale->invalidFields()));
                    }
                    break;

                case 'SaleCreditPayment' :
                    $loggedUser_id = $loggedUser['id'];

                    $this->request->data['SaleCreditPayment']['created_by'] = $loggedUser_id;
                    $this->SaleCreditPayment->create();

                    # save the data
                    if ($this->SaleCreditPayment->save($this->request->data)) {
                        $last_dt = $this->request->data['SaleCreditPayment']['pay_date'];
                        $d = new DateTime($last_dt);
                        $d->modify('next month');

                        $data = array(
                            'id' => $this->SaleCreditPayment->id,
                            'last_paid_date' => $last_dt,
                            'next_credit_date' => $d->format('Y-m-d')
                        );

                        //Cache the last customer and sale the user was working with
                        $last_entry = array('Sale'=>array(
                            'id'=>$this->request->data['SaleCreditPayment']['sale_id'],
                            'customer_id'=>$this->request->data['SaleCreditPayment']['c_customer_id']
                        ));
                        $this->Session->write('last_entry',$last_entry);

                        return json_encode(array('code' => 0, 'data' => $data, 'mesg' => __('Data Saved')));
                    }
                    else {
                        return json_encode(array('code' => 1, 'mesg' => $this->SaleCreditPayment->invalidFields()));
                    }
                    break;
            }
        }
    }


    /**
     *
     * @param void
     * @return html
     * @access public
     */
    function repayment()
    {
        $loggedUser = $this->Auth->user();
        $loggedUser_id = $loggedUser['id'];

        /** Important, we need to set the default for the last Customer and sales transaction a user was working on. ** */

        if($this->Session->check('last_entry')){
            $last_entry = $this->Session->read('last_entry');
        }
        else{
            $last_entry = $this->Sale->find('first',array(
                'conditions'=>array('Sale.deleted'=>'n','Sale.created_by'=>$loggedUser_id),
                'fields'=>array('id','customer_id','created_by'),
                'order'=>array('Sale.id'=>'desc'),
                'recursive'=>-1
            ));
        }

        $creditors = $creditors_data_r = $this->Sale->find('all', array(
            'fields' => array('Sale.id','Sale.purchased_date','Sale.currency','Sale.interest','Sale.duration_in_month','Sale.opening_bal','Sale.tenor','Sale.interest_rate_decimal_places','Sale.purchase_type','Sale.invoice_number','Sale.vehicle_no','Sale.principal','Sale.deposit','Sale.cost'),
            'conditions' => array('Sale.deleted'=>'n','Sale.on_credit' => 'y'),
            'contain' => array(
                'Customer' => array(
                    'fields' => array('Customer.id', 'Customer.name'),
                ),
                'SaleItem' => array(
                    'fields' => array('SaleItem.id', 'SaleItem.quantity'),
                    'Item' =>array(
                        'fields' => array('Item.id', 'Item.name'),
                    )
                ),
                'SaleCreditPayment'=>array(
                    'fields' => array('SaleCreditPayment.id', 'SaleCreditPayment.pay_date','SaleCreditPayment.paid_amount'),
                )
            ),
            'order' => array('Sale.id' => 'desc'),
            'recursive' => 2
        ));

        $creditors = Set::combine($creditors, '{n}.Customer.id', '{n}.Customer.name');

        $creditors_data = array();
        foreach ($creditors_data_r as $key => $data) {
            $customer_id = $data['Customer']['id'];
            $sale_id = $data['Sale']['id'];
            $data['Sale']['SaleItem'] = $data['SaleItem'];
            $data['Sale']['SaleCreditPayment'] = $data['SaleCreditPayment'];
            //$data['Sale']['Sale'] = $data['Sale'];
            $amr  = $this->get_amortization_data($sale_id);
            $data['Sale']['Amortization'] = array(
                'tl_inerest_raw' => $amr['tl_inerest_raw'],
                'opening_bal_raw'=> $amr['opening_bal_raw']
            );

            /*$d1 = $data['Sale']['purchased_date']; //Smaller date
            $d2 = $data['Sale']['end_date']; //Bigger date
            $data['Sale']['duration_in_month'] = $this->count_months_between_dates($d1, $d2);*/

            if ($data['Sale']['SaleCreditPayment']) {
                $last_dt = $data['Sale']['SaleCreditPayment'][0]['pay_date']; // this is sorted on id desc, so the first index[0] is the last paid date
            }
            else {
                $last_dt = $data['Sale']['purchased_date'];
            }
            //$d = new DateTime($last_dt);
            //$d->modify('next month');

            $data['Sale']['last_paid_date'] = $last_dt;
            $data['Sale']['next_credit_date'] = date("Y-m-d", strtotime(date("Y-m-d", strtotime($last_dt)) . " +1 month"));

            $creditors_data[$customer_id]['Customer'] = $data['Customer'];
            $creditors_data[$customer_id]['Sale'][$sale_id] = $data['Sale'];

        }

        //debug($creditors_data);
        //exit;

        $pay_type_opt = $this->payment_types;
        $buying_usd_rate = $this->buying_usd_rate;
        $selling_usd_rate = $this->selling_usd_rate;
        $currency_opts = $this->currency_types;

        $page_title = 'Sale Repayment';

        $this->set(compact('page_title','pay_type_opt', 'currency_opts', 'creditors', 'creditors_data', 'buying_usd_rate', 'selling_usd_rate','last_entry'));

    }


    function edit_repayment()
    {
        $pay_type_opt = $this->payment_types;
        $this->set(compact('pay_type_opt'));
    }


    /**
     * This function add a new record to the database
     * @name add
     * @param void
     * @return Json data
     * @access public
     */
    function update(){
        # Get the user session data
        $loggedUser = $this->Auth->user();
        # check whether the HTTP Request is an ajax request
        if ($this->request->is('ajax')) {
            # disable the rendering of the layout
            $this->autoRender = false;
            $this->autoLayout = false;
            # retrieve the model
            $model = ucfirst($_POST['model']);
            # Check the model
            switch ($model) {
                case 'SaleCreditPayment' :
                    $upt_id = ($_POST['row_id'] != 'null') ? $_POST['row_id'] : false;
                    $loggedUser_id = $loggedUser['id'];

                    $this->SaleCreditPayment->id = $upt_id;
                    $this->request->data['SaleCreditPayment']['modified_by'] = $loggedUser_id;

                    # save the data
                    if ($this->SaleCreditPayment->save($this->request->data)) {
                        return json_encode(array('code' => 0, 'mesg' => __('Data Saved')));
                    }
                    else {
                        return json_encode(array('code' => 1, 'mesg' => $this->SaleCreditPayment->invalidFields()));
                    }
                    break;
            }
        }
    }


    /**
     *
     * @param void
     * @return html
     * @access public
     */
    function load()
    {
        $this->autoRender = false;
        $this->autoLayout = false;

        /** Loading */
        //$userData = $this->Item->getById($_POST['data-id']);
        $sale_repayment = $this->SaleCreditPayment->find('first', array(
            'conditions' => array('SaleCreditPayment.id' => $_POST['data-id']),
            'recursive' => -1
        ));


        if ($sale_repayment) {
            return json_encode(array('code' => 0, 'data' => $sale_repayment, 'mesg' => __('Data Found')));
        }
        else {
            return json_encode(array('code' => 1, 'data' => array(), 'mesg' => __('No Record Found')));
        }
    }

    #
    function delete_()
    {
        if ($this->request->is('ajax')) {
            $this->autoRender = false;
            $this->autoLayout = false;

            $loggedUser =  $this->Auth->user();
            $loggedUser_id = $loggedUser['id'];

            $ids = $_POST['ids'];
            $modObj = ClassRegistry::init('SaleCreditPayment');
            $result = $modObj->updateAll(
                array('SaleCreditPayment.deleted' => "'y'",'SaleCreditPayment.modified_by' => $loggedUser_id),
                array('SaleCreditPayment.id' => $ids)
            );

            if ($result) {
                echo json_encode(array('code' => 0, 'mesg' => __('Selected Item(s) have been successfully deleted')));
            }
            else {
                echo json_encode(array('code' => 1, 'mesg' => __('Selected Item(s) cannot be deleted')));
            }
        }
    }


    /**
     * @name get
     * @param void
     * @return Json Data
     */
    function get()
    {
        # disable the rendering of the layout
        $this->autoRender = false;
        $this->autoLayout = false;

        /**  Get posted data */
        $page = isset($_POST['page']) ? $_POST['page'] : 1;
        /** The current page */
        $sortname = isset($_POST['sortname']) ? $_POST['sortname'] : 'id';
        /** Sort column */
        $sortorder = isset($_POST['sortorder']) ? $_POST['sortorder'] : 'desc';
        /** Sort order */
        $qtype = isset($_POST['qtype']) ? $_POST['qtype'] : '';
        /** Search column */
        $search_query = isset($_POST['query']) ? $_POST['query'] : '';
        /** Search string */
        $rp = isset($_POST['rp']) ? $_POST['rp'] : 10;
        $limit = $rp;
        $start = ($page - 1) * $rp;

        $condition_array = array('SaleCreditPayment.deleted' => 'n');
        if (!empty($search_query)) {
            if ($qtype == 'name') {
                $condition_array = array(
                    'SaleCreditPayment.name LIKE' => $search_query . '%',
                    'SaleCreditPayment.deleted' => 'n'
                );
            }
            else {
                $condition_array = array(
                    "SaleCreditPayment.$qtype LIKE" => $search_query . '%',
                    'SaleCreditPayment.deleted' => 'n'
                );
            }
        }


        $fields = array('SaleCreditPayment.id', 'SaleCreditPayment.sale_id', 'SaleCreditPayment.paid_amount', 'SaleCreditPayment.pay_date', 'SaleCreditPayment.pay_type', 'SaleCreditPayment.comments');
        $users = $this->SaleCreditPayment->find('all', array('fields' => $fields, 'conditions' => $condition_array, 'order' => "SaleCreditPayment.$sortname $sortorder", 'limit' => $start . ',' . $limit, 'recursive' => -1));
        $usersCount = $this->SaleCreditPayment->find('count', array('conditions' => $condition_array, 'recursive' => -1));

        $total_records = $usersCount;

        if ($users) {
            $return_arr = array();
            foreach ($users as $obj) {

                $sale = $this->Sale->find('first', array(
                    'fields' => array('Sale.id', 'Sale.customer_id'),
                    'conditions' => array('Sale.id' => $obj['SaleCreditPayment']['sale_id']),
                    'contain' => array('Customer' => array(
                        'fields' => array('Customer.id', 'Customer.name')
                    )),
                    'recursive' => 1
                ));

                $return_arr[] = array(
                    'id' => $obj['SaleCreditPayment']['id'],
                    'cell' => array(
                        $obj['SaleCreditPayment']['id'],
                        $sale['Customer']['name'],
                        $this->formatMoney($obj['SaleCreditPayment']['paid_amount']),
                        $obj['SaleCreditPayment']['pay_date'],
                        $obj['SaleCreditPayment']['pay_type'],
                        $obj['SaleCreditPayment']['comments']
                    )
                );
            }
            return json_encode(array('success' => true, 'total' => $total_records, 'page' => $page, 'rows' => $return_arr));
        }
        else {
            return json_encode(array('success' => false, 'total' => $total_records, 'page' => $page, 'rows' => array()));
        }

    }


    function print_receipt($id = null)
    {
        $this->layout = 'print_receipt_layout';

        $json_data = $this->SaleCreditPayment->find('first', array(
            'conditions' => array('SaleCreditPayment.id'=>$id),
            'contain' => array(
                'Sale'=>array('Customer')
            ),
            'recursive' => 2
        ));
        $sale_id = $json_data['Sale']['id'];
        $amortise_data = $this->get_repayment($sale_id);
        $outstanding_balance = $amortise_data['tl_outstanding'];
        //debug($amortise_data);
        $json_data['Customer'] = $json_data['Sale']['Customer'];

        //debug($json_data);
        $controller = $this;
        $print_title = "Payment Receipt";
        $this->set(compact('json_data','print_title','outstanding_balance','controller'));
    }

    function print_sale_receipt($id = null)
    {
        $this->layout = 'print_receipt_layout';

        $json_data = $this->Sale->find('first', array(
            'conditions' => array('Sale.id'=>$id),
            'contain' => array(
                'Customer','SaleItem'=>array('Item')
            ),
            'recursive' => 2
        ));

       /* $json_data = $this->SaleCreditPayment->find('first', array(
            'conditions' => array('SaleCreditPayment.id'=>$id),
            'contain' => array(
                'Sale'=>array('Customer')
            ),
            'recursive' => 2
        ));*/
        //$sale_id = $json_data['Sale']['id'];
        $amortise_data = $this->get_repayment($id);
        $outstanding_balance = $amortise_data['tl_outstanding'];
        //debug($amortise_data);
       // $json_data['Customer'] = $json_data['Sale']['Customer'];

        //debug($json_data);
        $controller = $this;
        $print_title = "Payment Receipt";
        $this->set(compact('json_data','print_title','outstanding_balance','controller'));
    }


   /* function print_invoice($id = null)
    {
        $this->layout = 'print_invoice_layout';

        $json_data = $this->Sale->find('first', array(
            'conditions' => array('Sale.id'=>$id),
            'contain' => array(
                'Customer','SaleItem'=>array('Item')
            ),
            'recursive' => 2
        ));

        $sales_items = array();
        $tl_amount = 0.00;
        foreach($json_data['SaleItem'] as $item){
            $quantity = floatval($item['quantity']);
            $unit_price = floatval($item['unit_price']);
            $amount = $quantity * $unit_price;
            $sales_items[] = array(
                'quantity'=>$quantity,
                'description'=>$item['Item']['name'],
                'rate'=>$this->formatNumber($unit_price,'money'),
                'amount'=> $this->formatNumber($amount,'money')
            );
            //$tl_amount = $tl_amount + $amount;
        }
        $json_data['SaleItem'] = $sales_items;

        $extra_data = array();
        //Deposit
        $extra_data[] = array(
            'quantity'=>'',
            'description'=>'Deposit',
            'rate'=>$this->formatNumber($json_data['Sale']['deposit'],'money'),
            'amount'=> $this->formatNumber($json_data['Sale']['deposit'],'money')
        );

        //Discount
        $extra_data[] = array(
            'quantity'=>'',
            'description'=>'Discount Allowed',
            'rate'=>'-'.$this->formatNumber($json_data['Sale']['discount_amount'],'money'),
            'amount'=> '-'.$this->formatNumber($json_data['Sale']['discount_amount'],'money'),
        );
        $bal = $tl_amount - floatval($json_data['Sale']['discount_amount']);
        $tax = floatval($json_data['Sale']['tax']);
        $tax_amount = ($tax/100)*$bal;
        //Tax
        $extra_data[] = array(
            'quantity'=>'',
            'description'=>'Value Added Tax',
            'rate'=>$this->formatNumber($tax).'%',
            'amount'=> $this->formatNumber($tax_amount,'money'),
        );

        $json_data['Extra']=$extra_data;
        $json_data['Total']= $this->formatNumber($bal + $tax_amount,'money');

        //debug($json_data);

        $print_title = "Invoice";
        $this->set(compact('json_data','print_title'));
    }*/


    function search_proforma()
    {
        $this->autoRender = false;
        $this->autoLayout = false;

        $query = trim($_POST['query']);
        $proforma_data = $this->Proforma->find('first', array(
            'fields'=>array('Proforma.id','Proforma.invoice_number','Proforma.customer_id'),
            'conditions' => array('Proforma.invoice_number' => $query),
            'contain' => array('ProformaItem' => array('fields'=>array('ProformaItem.id','ProformaItem.item_id','ProformaItem.quantity'))),
            'recursive' => 1
        ));

        if ($proforma_data) {
            return json_encode(array('code' => 0, 'data' => $proforma_data, 'mesg' => __('Data Found')));
        }
        else {
            return json_encode(array('code' => 1, 'data' => array(), 'mesg' => __('No Record Found')));
        }
    }
}
